#include "../include/Multigrid_Solver_2D.h"
// double basic_f2rd(double *P)
// {
//     return 6.0 * (P[0] + P[1]);
// };

// double basic_f(double *P)
// {
//     return P[0] * P[0] * P[0] + P[1] * P[1] * P[1] - 10;
// };

double basic_f2rd(double * P)
{
    return  (-2*sin(P[0])*sin(P[1])+sin(P[1])*cos(P[0])*cos(P[0])+sin(P[0])*cos(P[1])*cos(P[1]))*exp(sin(P[0])*sin(P[1]));
};

double basic_f(double *P)
{
    return exp(sin(P[0]*sin(P[1])));
};

int main()
{
    int n = 512;
    Function _rhsF = basic_f2rd;
    Function _bcf = basic_f;
    double _a[2] = {0, 0};
    MG_2D case1;
    case1.Initialize(n, _rhsF, _bcf);

    VectorXd u_ = case1.get_u_origin();
    VectorXd f_ = case1.get_f_origin();
    VectorXd r_origin,r_;
    double h = case1.get_h();
    case1.setRestircType(1);
    case1.setIntpType(1);
    case1.setSmoothType(2);
    r_origin=case1.ResidualSolver(u_, f_, h);

    double r_origin_norm=r_origin.lpNorm<Eigen::Infinity>();
int cnt;

    // u_=case1.FMGcycle(f_,h);

    // r_=case1.ResidualSolver(u_,f_,h);


// std::cout<<r_.lpNorm<Eigen::Infinity>()/r_origin_norm<<std::endl;
  

for (cnt=1;cnt<=50;cnt++)
{
    u_=case1.Vcycle(u_,f_,h);
    r_=case1.ResidualSolver(u_,f_,h);
    if (r_.lpNorm<Eigen::Infinity>() <= r_origin_norm*1e-8)
    break;
};
std::cout<<cnt<<std::endl;
std::cout<<r_.lpNorm<Eigen::Infinity>()/r_origin_norm<<std::endl;
  
//    std::cout << "_BC:\n"
//               << case1.get_BC() << std::endl;
//     std::cout << "_u_origin\n"
//               << u_ << std::endl;
//     std::cout << "_f_origin\n"
//               << f_ << std::endl;
//     std::cout << "N = " << 1.0 / h << std::endl;
    // for(int i=1;i<=1;i++)
    // _u = case1.SmoothingforVC(_u, _f, h);
    // _r=case1.ResidualSolver(_u, _f, h);
    // std::cout<<"_r_origin:"<< _r_origin <<std::endl;
    // std::cout << "_r: \n"<<_r << std::endl;
    // _r=case1.RestrictSolver(_r);
    // std::cout<<"Restric r: \n"<<_r<<std::endl;
    // std::cout<<"\n"<<std::endl;
    // _r=case1.IntpSolver(_r);
    // std::cout<<"Intp r: \n"<<_r<<std::endl;

};